﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SHomeWorkshop.LunarConcept
{
    /// <summary>
    /// 一次“修改”中某个“动作”的类型。
    /// 
    /// ModifingsList中的Undo()和Redo()方法将根据某Action实例的ActionType属性值来决定如何进行撤销或重做操作。
    /// </summary>
    public enum ActionType
    {
        PropertyChanged,                   //修改属性——大部分操作都是这个类型！
        WidgetAdded,                       //添加一个Widget
        WidgetDeleted,                     //删除一个Widget
        PaperSizeSetting,                   //设置页面尺寸
        PaperDirectionSetting,              //设置页面指向（纵向或横向）
        
        PageLongSideMultipleChanged,        //设置了页面长边的扩展倍数
        PageShortSideMultipleChanged,       //设置了页面短边的扩展倍数

        MovePageEditor,                     //更改编辑器索引
        PageEditorAdded,                    //追加一个新编辑器
        PageEditorDeleted,                  //删除一个编辑器

        DefaultFontSizeChanged,             //文档默认字号
        //DefaultForegroundChanged,           //默认部件前景色被修改//2012年6月14日被废弃。与部件相关的都只应由部件样式管理，避免冲突。
        DefaultBackgroundChanged,           //默认部件背景色被修改
        TileMode,                           //页面背景图翻转模式被修改
        WidgetSelectionAdornerBrushChanged, //部件选定框色被修改

        PageHeaderChanged,                  //更改了页眉文本
        PageFooterChanged,                  //更改了页脚文本
        PageTitleChanged,                   //更改了页面标题
        PageLeftSideColorChanged,           //更改了页面页眉区底色
        PageRightSideColorChanged,          //更改了页面页脚区底色
        SetPageCommentText,                 //设置页面备注
        ShowPageNumber,                     //设置是否显示页码

        WidgetStartCtrlBrushChanged,        //更改了线型部件首控制点色彩
        WidgetCenterCtrlBrushChanged,       //更改了线型部件中控制点色彩
        WidgetEndCtrlBrushChanged,      　  //更改了线型部件尾控制点色彩
        
        SetWidgetStyle,                     //设置部件样式
        SetAssistGridForm,                  //文档背景网格线（编辑区网格线）样式

        //TODO: 其它动作类型应添加在此处。
    };

    /// <summary>
    /// 创建时间：2011年12月27日
    /// 创建者：  杨震宇
    /// 
    /// 主要用途：用于“撤销与重做”的一个类。表示“一次“修改”中的一个“操作（步骤）”。
    /// 
    /// ★★注意：此类与Action类是实际使用的记录“修改操作信息”的类。
    ///           在使用泛型的ImodifingManager/ModifingList等类时，需要提供两个实际可用的类：
    ///               ①与“修改”有关的信息类；②与“修改”中的“动作”有关的信息类。
    ///           
    ///           本程序中，与“修改”有关的信息类就是此类；与“修改”中某个“动作”有关的信息类是Action类。
    ///           
    ///           ①这是个真正使用的Action类。
    ///           ②如果是与一次“修改”有关的信息，则使用ModifingInfo类。
    ///           由于2011年12月27日晚间使用泛型改造了ModifingList、ModifingItem、IModifingItemManager等类和接口，
    ///           因此，这些类和接口几乎可以使用任意类型的Action数据。
    /// </summary>
    public class Action
    {
        #region 构造方法=====================================================================================================

        /// <summary>
        /// [构造方法]如果是文档全局设置等与具体部件无关的操作。应使用此构造方法。
        /// ——如果是涉及具体某个页面设置，请使用第二个重载版本的构造方法。
        /// ——如果是涉及某个具体部件的动作，请使用第三个重载版本的构造方法。
        /// </summary>
        /// <param name="actionType">动作类型。</param>
        /// <param name="oldDataText">动作执行前的旧数据的文本表示形式。</param>
        /// <param name="newDataText">动作执行前的旧数据的文本表示形式。</param>
        public Action(ActionType actionType, string oldDataText, string newDataText)
        {
            this.actionType = actionType;
            this.oldDataText = oldDataText;
            this.newDataText = newDataText;
        }

        /// <summary>
        /// [构造方法]用于对某个具体的页编辑器进行设置时的动作。
        /// </summary>
        /// <param name="actionType">动作类型。</param>
        /// <param name="pageEditorID">页编辑器ID。</param>
        /// <param name="oldDataText">动作执行前的旧数据的文本表示形式。</param>
        /// <param name="newDataText">动作执行前的旧数据的文本表示形式。</param>
        public Action(ActionType actionType, string pageEditorID, string oldDataText, string newDataText)
        {
            this.actionType = actionType;
            this.pageEditorID = pageEditorID;
            this.oldDataText = oldDataText;
            this.newDataText = newDataText;
        }

        /// <summary>
        /// [构造方法]用于添加、删除部件时。
        /// </summary>
        /// <param name="actionType">动作类型。</param>
        /// <param name="pageEditorID">页编辑器ID。</param>
        /// <param name="widgetID">相关的部件的ID。</param>
        /// <param name="oldDataText">动作执行前的旧数据的文本表示形式。</param>
        /// <param name="newDataText">动作执行前的旧数据的文本表示形式。</param>
        public Action(ActionType actionType, string pageEditorID, string widgetID, string oldDataText, string newDataText)
        {
            this.actionType = actionType;
            this.pageEditorID = pageEditorID;
            this.widgetID = widgetID;
            this.oldDataText = oldDataText;
            this.newDataText = newDataText;
        }

        /// <summary>
        /// [构造方法]用于增删页面。
        /// </summary>
        /// <param name="actionType">动作类型。</param>
        /// <param name="pageEditorID">页编辑器ID。</param>
        /// <param name="pageEditorIndex">页面编辑器索引。</param>
        /// <param name="oldDataText">动作执行前的旧数据的文本表示形式。</param>
        /// <param name="newDataText">动作执行前的旧数据的文本表示形式。</param>
        public Action(ActionType actionType, string pageEditorID, int pageEditorIndex,
            string oldDataText, string newDataText)
        {
            this.actionType = actionType;
            this.pageEditorID = pageEditorID;
            this.pageEditorIndex = pageEditorIndex;
            this.oldDataText = oldDataText;
            this.newDataText = newDataText;
        }

        /// <summary>
        /// [构造方法]与具体部件相关的动作，应使用此方法。
        /// ——使用此构造方法时，ActionType值为默认值：ActionType.PropertyChanging。
        /// </summary>
        /// <param name="pageEditorID">动作所涉及的部件所在的pageEditor的ID。</param>
        /// <param name="widgetID">动作所涉及的部件的ID。</param>
        /// <param name="widgetClassName">动作所涉及的部件的真实类名。（调用Widget.ClassName属性即可）</param>
        /// <param name="aliasName">动作所涉及的部件被修改的属性的名称。</param>
        /// <param name="oldDataText">动作执行前，此属性值的【文本表示形式】。</param>
        /// <param name="newDataText">动作执行后，此属性值的【文本表示形式】。</param>
        public Action(
            string pageEditorID,
            string widgetID,
            string widgetClassName,
            string propertyName,
            string oldDataText,
            string newDataText)
        {
            this.pageEditorID = pageEditorID;
            this.widgetID = widgetID;
            this.widgetClassName = widgetClassName;
            this.propertyName = propertyName;
            this.oldDataText = oldDataText;
            this.newDataText = newDataText;
        }

        #endregion

        #region 字段与属性===================================================================================================

        private ActionType actionType = ActionType.PropertyChanged;
        /// <summary>
        /// [只读]一次“修改”中某个“动作（步骤）”的动作类型。
        /// </summary>
        public ActionType ActionType
        {
            get { return actionType; }
        }

        private string newDataText;
        /// <summary>
        /// [只读]一次“修改”中某个“动作（步骤）”所携带的【动作执行后】的数据值的【文本表示形式】。
        /// </summary>
        public string NewDataText
        {
            get { return newDataText; }
        }

        private string oldDataText;
        /// <summary>
        /// [只读]一次“修改”中某个“动作（步骤）”所携带的【动作执行前】的数据值的【文本表示形式】。
        /// </summary>
        public string OldDataText
        {
            get { return oldDataText; }
        }

        private string pageEditorID = null;
        /// <summary>
        /// [只读]动作所涉及的部件所在的pageEditor的ID。
        /// ——不是所有操作都是针对部件进行的。因此此值不一定有用。
        /// </summary>
        public string PageEditorID
        {
            get { return pageEditorID; }
        }

        private int pageEditorIndex = -1;
        /// <summary>
        /// [只读]相关页面编辑器的索引。
        /// </summary>
        public int PageEditorIndex
        {
            get { return pageEditorIndex; }
        }

        private string propertyName;
        /// <summary>
        /// [只读]动作所针对的属性的名称。
        /// ——只有当ActionType为PropertyChanging时才有意义。
        /// </summary>
        public string PropertyName
        {
            get { return propertyName; }
        }

        private string widgetClassName = null;
        /// <summary>
        /// [只读]部件类名称。
        /// ——只有Action为PropertyChanging时才有意义。
        /// </summary>
        public string WidgetClassName
        {
            get { return widgetClassName; }
        }

        private string widgetID = null;
        /// <summary>
        /// [只读]部件ID。
        /// ——根据这个属性找到对哪个部件执行了修改动作。
        /// ——不是所有操作都是针对部件进行的。因此此值不一定有用。
        /// </summary>
        public string WidgetID
        {
            get { return widgetID; }
        }

        #endregion
    }
}
